package com.kgc.controller;

import com.kgc.config.WxPayConfig;
import com.kgc.entity.Order;
import com.kgc.service.OrderService;
import com.kgc.util.ResultAjax;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/wx")
public class WxPayController {

    @Autowired
    private OrderService orderService;

    private static final Logger logger = LoggerFactory.getLogger(WxPayController.class);

    @PostMapping("/zf")
    public ResultAjax zf(@RequestBody HashMap<String, String> map) {
        // 构建service
        NativePayService service = new NativePayService.Builder().config(WxPayConfig.instance().getCofig()).build();
        // request.setXxx(val)设置所需参数，具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();

        Amount amount = new Amount();
        amount.setTotal(1);
        // 设置订单支付金额 单位（分）
        request.setAmount(amount);
        // 设置应用ID
        request.setAppid(WxPayConfig.instance().getAppid());
        // 设置商户ID
        request.setMchid(WxPayConfig.instance().getMerchantId());
        // 设置订单描述信息
        request.setDescription("测试商品标题");
        // 设置异步回调地址
        request.setNotifyUrl(WxPayConfig.instance().getNotifyUrl());
        // 设置系统订单号
        String serialNumber = map.get("serialNumber");
        System.out.println("serialNumber" + serialNumber);
        request.setOutTradeNo(serialNumber);

        // 调用下单方法，得到应答
        PrepayResponse response = service.prepay(request);
        /**
         * 从应答中得到支付url，此url返回到前端vue，由vue生成二维码显示 并用手机扫码支付
         */
        return ResultAjax.success().add("pay_url", response.getCodeUrl());
    }

    /**
     * 异步回调
     *
     * @param signature     验签的签名值
     * @param serialNumber  验签的微信支付平台证书序列号/微信支付公钥ID
     * @param timestamp     验签的时间戳
     * @param nonce         验签的随机字符串
     * @param signatrueType 验签的算法类型
     * @param body          主体通知参数（JSON格式）
     * @param response      向应对象
     */
    @PostMapping("/wxNotify")
    public void wxNotify(@RequestHeader(value = "Wechatpay-Signature") String signature,
                         @RequestHeader(value = "Wechatpay-Serial") String serialNumber,
                         @RequestHeader(value = "Wechatpay-Timestamp") String timestamp,
                         @RequestHeader(value = "Wechatpay-Nonce") String nonce,
                         @RequestHeader(value = "Wechatpay-Signature-Type") String signatrueType,
                         @RequestBody String body,
                         HttpServletResponse response) {

        // 创建通知解析器
        NotificationParser notificationParser = new NotificationParser(WxPayConfig.instance().getCofig());
        // 创建微信支付通知请求参数
        RequestParam requestParam = new RequestParam.Builder()
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                .serialNumber(serialNumber)
                .signType(signatrueType)
                .body(body).build();
        // 解密后封装成的对象
        Transaction transaction = null;
        try {
            transaction = notificationParser.parse(requestParam, Transaction.class);
        } catch (ValidationException e) {
            logger.error("验证签名错误！", e);
            // 通知微信验证签名错误，需重新回调
            response.setStatus(500);
            return;
        }

        if (transaction.getTradeState() == TradeStateEnum.SUCCESS) {
            /**
             * 交易成功
             * 调用系统订单业务方法，更新订单状态，以及系统后续处理
             */
            logger.info(String.format("商户下单时传入的商户系统内部订单号[%s]", transaction.getOutTradeNo()));
            logger.info(String.format("微信支付侧订单的唯一标识[%s]", transaction.getTransactionId()));

            // 构造 map 并调用 orderService.orderPay(map)
            Map<String, Object> map = new HashMap<>();
            map.put("transactionId", transaction.getTransactionId()); // 微信支付交易号
            map.put("status", 1);
            map.put("tradeType", 1); // 支付类型，1 表示微信支付
            map.put("serialNumber", transaction.getOutTradeNo()); // 商户订单号
            orderService.orderPay(map);
            logger.info("付款完成！");
        }
        logger.info(transaction.toString());
        // 通知微信回调成功
        response.setStatus(200);
    }

    @PostMapping("/checkPayStatus")
    public ResultAjax checkPayStatus(@RequestBody Map<String, String> map) {
        String serialNumber = map.get("serialNumber");
        System.out.println("CHeckserialNumber" + serialNumber);
        // 检查订单支付状态
        Order order = orderService.selectBySerialNumber(serialNumber);
        if (order.getStatus() == 1 || order.getStatus() == 11) {
            return ResultAjax.success().add("status", "paid");
        } else {
            return ResultAjax.success().add("status", "unpaid");
        }
    }


}
